package com.hfzy.ihk.common.core.elasticsearch;


import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.hfzy.ihk.common.constants.GlobalStatic;
import com.hfzy.ihk.common.core.elasticsearch.entity.VersionCtrlErrorMsg;
import com.hfzy.ihk.common.core.elasticsearch.entity.OperationErrorMsg;
import com.hfzy.ihk.common.util.string.StringUtil;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Vector;

/**
 * Created by Administrator on 2018/5/30.
 *
 * @author wws
 */
@Component
@ConditionalOnProperty(prefix = "linkcall.elasticsearch",name = "enable")
public class ElasticsearchLocalCache implements DisposableBean,InitializingBean {

    private static Logger logger = LoggerFactory.getLogger(ElasticsearchLocalCache.class);

    private static List<VersionCtrlErrorMsg> versionCtrlErrorMsgMemoryCache = new Vector(1000);
    private static List<OperationErrorMsg> optErrorMsgMemoryCache = new Vector(1000);
    private static List<Map<String,Object>> callTaskRedisErrorMsgMemoryCache = new Vector(1000);

    @Value("${spring.application.name}")
    private String applicationName;
    @Value("${spring.profiles.active}")
    private String profile;

    private String cacheVersionErrorMsgFileName = "./msgCache/cacheVersionErrorMsg.log";
    private String cacheOptErrorMsgFileName = "./msgCache/cacheOptErrorMsg.log";
    private String callTaskRedisErrorMsgFileName = "./msgCache/callTaskRedisErrorMsgFileName.log";

    @Override
    public void afterPropertiesSet() throws Exception {

        logger.info("init ElasticsearchLocalCache bean");
        init();
    }

    //持久化到文件
    @Override
    public void destroy() throws Exception {
        logger.info("destroy ElasticsearchLocalCache bean");
        try {
            saveOptErrorFileBeforeDestroy();
        } catch (IOException e) {
          logger.error("异常：",e);
        }
        try {
            saveVersionErrorFileBeforeDestroy();
        } catch (IOException e) {
          logger.error("异常：",e);
        }
        try {
            saveCallTaskRedisBeforeDestroy();
        } catch (IOException e) {
            logger.error("异常：",e);
        }
    }

    public void init() throws Exception {

        if(!GlobalStatic.SYSTEM_ENV_PRO.equals(profile)){
            cacheVersionErrorMsgFileName = StringUtil.strConnect("msgCache/",applicationName,"-",profile,"/cacheVersionMsg.log");
            cacheOptErrorMsgFileName = StringUtil.strConnect("msgCache/",applicationName,"-",profile,"/cacheTransOptMsg.log");
            callTaskRedisErrorMsgFileName = StringUtil.strConnect("msgCache/",applicationName,"-",profile,"/cacheCallTaskRedisMsg.log");
        }

        logger.info("cacheVersionErrorMsgFile config path:{}",cacheVersionErrorMsgFileName);
        logger.info("cacheOptErrorMsgFileName config path:{}",cacheOptErrorMsgFileName);
        logger.info("callTaskRedisErrorMsgFileName config path:{}",callTaskRedisErrorMsgFileName);

        //从文件加载
        initVersionErrorFile();
        initOptErrorFile();
        initCallTaskRedisErrorFile();
    }

    private void saveVersionErrorFileBeforeDestroy() throws IOException {

        File cacheVersionMsgFile = new File(cacheVersionErrorMsgFileName);

        if(cacheVersionMsgFile.exists()) {
            cacheVersionMsgFile.delete();
        }

        if(versionCtrlErrorMsgMemoryCache.size()>0){

            for(VersionCtrlErrorMsg versionCtrlErrorMsg : versionCtrlErrorMsgMemoryCache){
                String msg = JSON.toJSONString(versionCtrlErrorMsg);
                logger.info("saving version msg to file:{}",msg);
                FileUtils.writeLines(cacheVersionMsgFile, Lists.newArrayList(msg),true);
            }
            logger.info("VersionCtrlErrorMsgMemoryCache has save to file");
        }

    }

    private void saveOptErrorFileBeforeDestroy() throws IOException {

        File cacheTransOptMsgFile = new File(cacheOptErrorMsgFileName);

        if(cacheTransOptMsgFile.exists()) {
            cacheTransOptMsgFile.delete();
        }

        if(optErrorMsgMemoryCache.size()>0){
            for(OperationErrorMsg operationErrorMsg : optErrorMsgMemoryCache){
                String msg = JSON.toJSONString(operationErrorMsg);
                logger.info("saving version msg to file:{}",msg);
                FileUtils.writeLines(cacheTransOptMsgFile, Lists.newArrayList(msg),true);
            }
            logger.info("optErrorMsgMemoryCache has save to file,path:{}",cacheTransOptMsgFile.getAbsolutePath());
        }
    }

    private void saveCallTaskRedisBeforeDestroy() throws IOException {

        File cacheCallTaskRedisMsgFile = new File(callTaskRedisErrorMsgFileName);

        if(cacheCallTaskRedisMsgFile.exists()) {
            cacheCallTaskRedisMsgFile.delete();
        }

        if(callTaskRedisErrorMsgMemoryCache.size()>0){
            for(Map<String,Object> map: callTaskRedisErrorMsgMemoryCache){
                String msg = JSON.toJSONString(map);
                logger.info("saving callTaskRedis msg to file:{}",msg);
                FileUtils.writeLines(cacheCallTaskRedisMsgFile, Lists.newArrayList(msg),true);
            }
            logger.info("callTaskRedisErrorMsgMemoryCache has save to file,path:{}",cacheCallTaskRedisMsgFile.getAbsolutePath());
        }
    }

    private void initVersionErrorFile() throws IOException {

        File cacheVersionMsgFile = new File(cacheVersionErrorMsgFileName);

        if(!cacheVersionMsgFile.exists()){
            logger.info("no found versionFile:{}",cacheVersionMsgFile.getAbsolutePath());
//            FileUtils.forceMkdirParent(cacheVersionMsgFile);
//            cacheVersionMsgFile.createNewFile();
            return;
        }else if(FileUtils.sizeOf(cacheVersionMsgFile)>0){
            try {

                List<String> contentList = FileUtils.readLines(cacheVersionMsgFile, Charset.defaultCharset());
                for(String msgStr:contentList){
                    versionCtrlErrorMsgMemoryCache.add(JSON.toJavaObject(JSON.parseObject(msgStr),VersionCtrlErrorMsg.class));
                }

                cacheVersionMsgFile.delete();

            } catch (IOException e) {
              logger.error("异常：",e);
            }
            logger.info("VersionCtrlErrorMsgMemoryCache has init from file.size:{}",versionCtrlErrorMsgMemoryCache.size());
        }
    }

    private void initOptErrorFile() throws IOException{

        File cacheTransOptMsgFile = new File(cacheOptErrorMsgFileName);

        if(!cacheTransOptMsgFile.exists()){
            logger.info("no found optFile:{}",cacheTransOptMsgFile.getAbsolutePath());
//            FileUtils.forceMkdirParent(cacheTransOptMsgFile);
//            cacheTransOptMsgFile.createNewFile();
            return;
        }else if(FileUtils.sizeOf(cacheTransOptMsgFile)>0){
            try {
                List<String> contentList = FileUtils.readLines(cacheTransOptMsgFile, Charset.defaultCharset());
                for(String msgStr:contentList){
                    optErrorMsgMemoryCache.add(JSON.toJavaObject(JSON.parseObject(msgStr),OperationErrorMsg.class));
                }

                cacheTransOptMsgFile.delete();

            } catch (IOException e) {
              logger.error("异常：",e);
            }
            logger.info("optErrorMsgMemoryCache has init from file.size:{}", optErrorMsgMemoryCache.size());
        }
    }

    private void initCallTaskRedisErrorFile() throws IOException{

        File cacheCallTaskRedisMsgFile = new File(callTaskRedisErrorMsgFileName);

        if(!cacheCallTaskRedisMsgFile.exists()){
            logger.info("no found callTaskRedisFile:{}",cacheCallTaskRedisMsgFile.getAbsolutePath());
            return;
        }else if(FileUtils.sizeOf(cacheCallTaskRedisMsgFile)>0){
            try {
                List<String> contentList = FileUtils.readLines(cacheCallTaskRedisMsgFile, Charset.defaultCharset());
                for(String msgStr:contentList){
                    callTaskRedisErrorMsgMemoryCache.add(JSON.toJavaObject(JSON.parseObject(msgStr),Map.class));
                }

                cacheCallTaskRedisMsgFile.delete();

            } catch (IOException e) {
                logger.error("异常：",e);
            }
            logger.info("optErrorMsgMemoryCache has init from file.size:{}", callTaskRedisErrorMsgMemoryCache.size());
        }
    }

    public static void put(VersionCtrlErrorMsg msg){
        if(msg == null) {
            return;
        }

        versionCtrlErrorMsgMemoryCache.add(msg);
    }

    public static void put(OperationErrorMsg msg){
        if(msg == null) {
            return;
        }

        optErrorMsgMemoryCache.add(msg);
    }

    public static void put(Map<String,Object> msg){
        if(msg == null) {
            return;
        }

        callTaskRedisErrorMsgMemoryCache.add(msg);
    }

    public static List<VersionCtrlErrorMsg> getVersionErrorMsgMemoryCache() {
        return versionCtrlErrorMsgMemoryCache;
    }

    public static List<OperationErrorMsg> getOptErrorMsgMemoryCache() {
        return optErrorMsgMemoryCache;
    }

    public static List<Map<String,Object>> getCallTaskRedisErrorMsgMemoryCache() {
        return callTaskRedisErrorMsgMemoryCache;
    }

    public static int getVersionErrorMsgMemoryCacheSize() {
        return versionCtrlErrorMsgMemoryCache.size();
    }

    public static int getOptErrorMsgMemoryCacheSize() {

        return optErrorMsgMemoryCache.size();
    }

    public static void clearCrmTransMsg(){
        optErrorMsgMemoryCache.clear();
    }

    public static void clearVersionErrorMsg(){
        versionCtrlErrorMsgMemoryCache.clear();
    }

    public static void remove(OperationErrorMsg msg){
        optErrorMsgMemoryCache.remove(msg);
    }

    public static void remove(VersionCtrlErrorMsg msg){
        versionCtrlErrorMsgMemoryCache.remove(msg);
    }

    public static void remove(Map<String,Object> msg){
        callTaskRedisErrorMsgMemoryCache.remove(msg);
    }
}
